package com.summer.data.rs.map;

import com.summer.data.dialect.Dialect;
import com.summer.data.logging.Logger;
import com.summer.data.logging.LoggerFactory;
import com.summer.data.rs.MapFun;
import com.summer.data.table.column.*;
import com.summer.data.type.NocaseMetaData;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * @author 345480567@qq.com
 */
public abstract class AbstractResultSetMapFun<T> implements MapFun<ResultSet, T> {

    static Logger logger = LoggerFactory.getLogger(AbstractResultSetMapFun.class);

    protected Dialect dialect;

    public void setDialect(Dialect dialect) {
        this.dialect = dialect;
    }

    private NocaseMetaData nocaseMetaData;

    protected Integer getColumnIndex(ResultSet resultSet, String colName, Dialect dialect) throws SQLException {
        if (nocaseMetaData == null) {
            nocaseMetaData = new NocaseMetaData(resultSet.getMetaData(), dialect);
        }

        Integer index = nocaseMetaData.findColumn(colName);
        return index;
    }

    @Override
    public void mapBegin(ResultSet resultSet) throws SQLException {
    }

    @Override
    public void mapEnd(ResultSet resultSet) throws SQLException {
    }

    public void helpFetchNotNull(ResultSet resultSet, Integer index, Object obj, Field field) throws SQLException, IllegalAccessException {

        Class<?> fieldType = field.getType();
        field.setAccessible(true);

        // 时间
        if (Date.class.isAssignableFrom(fieldType) || LocalDate.class.isAssignableFrom(fieldType)) {
            LocalDate value = DateColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        if (LocalDateTime.class.isAssignableFrom(fieldType)) {
            LocalDateTime value = DateTimeColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        if (LocalTime.class.isAssignableFrom(fieldType) || Time.class.isAssignableFrom(fieldType)) {
            LocalTime value = TimeColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        if (Timestamp.class.isAssignableFrom(fieldType)) {
            Timestamp value = TimestampColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        // Boolean
        if (Boolean.class.isAssignableFrom(fieldType)) {
            Boolean value = BoolColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        // 数字
        if (Integer.class.isAssignableFrom(fieldType)) {
            Integer value = IntegerColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        if (Float.class.isAssignableFrom(fieldType)) {
            Float value = FloatColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        if (Double.class.isAssignableFrom(fieldType)) {
            Double value = DoubleColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        if (BigDecimal.class.isAssignableFrom(fieldType)) {
            BigDecimal value = DecimalColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        // 字符串
        if (String.class.isAssignableFrom(fieldType)) {
            String value = StringColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        if (Clob.class.isAssignableFrom(fieldType)) {
            String value = ClobColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

        if (Blob.class.isAssignableFrom(fieldType)) {
            byte[] value = BlobColumn.getValue(resultSet, index);
            field.set(obj, value);
        }

    }

}
